跳到主要内容
import { makeAutoObservable, runInAction } from 'mobx';
import type { CartItem, Product } from './types';

const MOCK_PRODUCTS: Product[] = [
{
id: 1,
name: '无线降噪耳机',
price: 299,
image: '🎧',
description: '沉浸式音质体验',
},
{
id: 2,
name: '智能运动手表',
price: 199,
image: '⌚️',
description: '全天候健康监测',
},
{
id: 3,
name: '手机',
price: 399,
image: '📱',
description: '拥抱科技,享受未来',
},
{
id: 4,
name: '机械键盘',
price: 69,
image: '⌨️',
description: '静音完美手感',
},
];

class CartStore {
cartItems: CartItem[] = [];
private sharedWorker: SharedWorker | undefined;

constructor() {
makeAutoObservable(this);

if (typeof SharedWorker !== 'undefined') {
const sharedWorker = new SharedWorker(
new URL('../workers/cart.work.ts', import.meta.url),
{
type: 'module', // 必须
credentials: 'same-origin',
},
);

// 当收到消息后
sharedWorker.port.onmessage = e => {
runInAction(() => {
this.cartItems = e.data;
});
};

this.sharedWorker = sharedWorker;

sharedWorker.port.start();
}
}

// 获取所有商品列表
get products() {
return MOCK_PRODUCTS;
}

// 计算总价(MobX 计算属性)
get totalPrice() {
return this.cartItems.reduce(
(total, item) => total + item.price * item.quantity,
0,
);
}

// 计算商品总数量
get totalQuantity() {
return this.cartItems.reduce((sum, item) => sum + item.quantity, 0);
}

// 添加到购物车
addToCart = (product: Product) => {
const existingItem = this.cartItems.find(item => item.id === product.id);

if (existingItem) {
existingItem.quantity += 1;
} else {
this.cartItems.push({
...product,
quantity: 1,
});
}
this.synchronizeData();
};

// 增加数量
increaseQuantity = (id: number) => {
const item = this.cartItems.find(item => item.id === id);

if (item) {
item.quantity += 1;
}
this.synchronizeData();
};
// 减少数量
decreaseQuantity = (id: number) => {
const item = this.cartItems.find(item => item.id === id);
if (item) {
if (item.quantity > 1) {
item.quantity -= 1;
} else {
this.removeFromCart(id);
}
}
this.synchronizeData();
};
// 移除商品
removeFromCart = (id: number) => {
this.cartItems = this.cartItems.filter(item => item.id !== id);
this.synchronizeData();
};

/** 同浏览器同步购物车数据 */
private synchronizeData() {
// 更新同浏览器页面逻辑
if (this.sharedWorker) {
if (this.sharedWorker.port.postMessage) {
// 将消息发送给同浏览器其他页面
this.sharedWorker.port.postMessage(
this.cartItems.reduce(
(cart: CartItem[], item) => [...cart, { ...item }],
[],
),
);
}
}
}
}

export const cartStore = new CartStore();